#include <iostream>
#include <cstddef> // 或者 #include <stddef.h>
#include <cstdint> // 或者 #include <stdint.h>

using namespace std;
template <typename T> // 定义一个模板函数，允许使用不同的数据类型
class LinkedList
{
private:
    struct Node // 定义一个内部结构体Node，表示链表中的节点
    {
        T data;                                              // 存储节点的数据
        Node *next;                                          // 指向下一个节点的指针
        Node(const T &value) : data(value), next(nullptr) {} // 构造函数，初始化节点数据和指针
    };

    Node *head; // 头节点指针，指向链表的第一个节点

public:
    LinkedList() : head(nullptr) {} // 构造函数，初始化头节点为空

    ~LinkedList() // 析构函数，释放链表中所有节点的内存
    {
        while (head != nullptr)
        {
            Node *temp = head;
            head = head->next;
            delete temp;
        }
    }

    void push_front(const T &value) // 在链表头部插入一个新节点
    {
        Node *newNode = new Node(value); // 创建新节点并分配内存
        newNode->next = head;            // 将新节点的next指向当前的头节点
        head = newNode;                  // 更新头节点为新节点
    }

    void pop_front() // 移除链表头部的节点
    {
        if (head != nullptr) // 如果链表不为空
        {
            Node *temp = head; // 保存头节点的指针
            head = head->next; // 将头节点更新为下一个节点
            delete temp;       // 删除原头节点
        }
    }

    bool empty() const // 检查链表是否为空
    {
        return head == nullptr;
    }

    void print() const // 打印链表中的所有元素
    {
        Node *current = head; // 从头节点开始遍历
        while (current != nullptr)
        {
            std::cout << current->data << " -> "; // 输出当前节点的数据
            current = current->next;              // 移动到下一个节点
        }
        std::cout << "nullptr" << std::endl; // 输出链表结束标志
    }
};
int main()
{
    LinkedList<int> list; // 创建一个整数类型的链表对象
    list.push_front(1);   // 在链表头部插入元素1
    list.push_front(2);   // 在链表头部插入元素2
    list.push_front(3);   // 在链表头部插入元素3
    list.print();         // 输出链表内容：3 -> 2 -> 1 -> nullptr
    list.pop_front();     // 移除链表头部的元素（即元素3）
    list.print();         // 输出链表内容：2 -> 1 -> nullptr
    return 0;
}
